package com.zhongli.devplatform.utils.im;

import com.zhongli.devplatform.component.im.TLSSigAPIGenerater;
import com.zhongli.devplatform.constant.im.TencentIMRestAPIConstant;
import com.zhongli.devplatform.component.SpringUtil;
import org.springframework.util.Assert;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;

/**
 * 腾讯IM Rest API 相关工具类
 * @author WuXiCheng
 * @version 1.0
 */
public class TencentIMRestAPIUtil {

    private static HashSet<String> serviceNames;

    private static HashMap<String, String> fieldValueMap;

    static {
        initReflection();
    }

    /**
     * 服务中 是否 存在该服务
     * @param serviceName   需要验证的serviceName
     * @return  true 存在 false 不存在
     */
    public static Boolean checkServiceName(String serviceName) {

        if(serviceName == null)
            return false;

        serviceName = serviceName.trim();

        if(serviceName.equals(""))
            return false;

        serviceName = serviceName.toLowerCase();

        return getServiceNames().contains(serviceName);
    }

    /**
     * 获取service的列表
     * @see TencentIMRestAPIConstant 的变量名称作为serviceName
     * @return
     */
    public static HashSet<String> getServiceNames() {
        if(serviceNames == null)
            initReflection();
        return serviceNames;
    }

    /**
     * 根据serviceName 获取对应的 api 地址
     * @param serviceName
     * @return
     * @throws Exception
     */
    public static String getServiceSubUrl(String serviceName){
        Assert.notNull(serviceName, "serviceName不能为Null");

        if(fieldValueMap == null)
            initReflection();

        serviceName = serviceName.trim().toLowerCase();

        String value = fieldValueMap.get(serviceName);

        Assert.notNull(value, "获取到的值为Null\tserviceName:" + serviceName);

        return value;
    }

    /**
     * 根据 serviceName 获取该 api 的完整请求地址
     * @param serviceName
     * @return
     * @throws Exception
     */
    public static String getServiceFullUrl(String serviceName) throws Exception {
        String serviceUrl = getServiceSubUrl(serviceName);
        return buildUrl(serviceUrl);
    }

    /**
     * 初始化
     */
    private static void initReflection(){
        serviceNames = new HashSet<>();
        fieldValueMap = new HashMap<>();

        Class<?> clazz = TencentIMRestAPIConstant.class;

        Field[] fields = clazz.getDeclaredFields();

        // 获取静态变量名称
        for(Field field : fields){
            if(Modifier.isStatic(field.getModifiers())){
                String fieldName = field.getName().toLowerCase();
                serviceNames.add(fieldName);

                try {
                    String value = (String) field.get(TencentIMRestAPIConstant.class);
                    fieldValueMap.put(fieldName, value);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    continue;
                }
            }
        }
    }

    /**
     * 生成 Tencent IM Rest API 请求URL
     * @param serviceUrl    请求接口URL
     * @param sdkAppId      SDKAppID
     * @param identifier    App管理员账号
     * @param userSig       App管理员账号的UserSig
     * @param random        32位无符号随机数 0 - 4294967295
     * @return              URL
     */
    public static String buildUrl(String serviceUrl, Long sdkAppId, String identifier, String userSig, Long random){

        StringBuilder sb = new StringBuilder(TencentIMRestAPIConstant.BASE_URL);
        sb.append(serviceUrl);

        String param = String.join("&",
                "?sdkappid=" + sdkAppId,
                "identifier=" + identifier,
                "usersig=" + userSig,
                "random=" + random,
                "contenttype=json");

        sb.append(param);

        return sb.toString();
    }

    /**
     * 生成 Tencent IM Rest API 请求URL
     * @param serviceUrl
     * @return
     */
    public static String buildUrl(String serviceUrl){

        serviceUrl = serviceUrl.trim();
        boolean nullOrEmpty = serviceUrl != null && !serviceUrl.equals("");

        Assert.isTrue(nullOrEmpty, "serviceUrl 不能为 NULL 或 空！");

        TLSSigAPIGenerater sigGenerater = SpringUtil.getBean(TLSSigAPIGenerater.class);

        Long sdkAppId = sigGenerater.getSdkAppId();
//        String secretKey = sigGenerater.getSecretKey();
        String identifier = sigGenerater.getAdminName();

        String userSig = sigGenerater.genSig(identifier, 60 * 60 * 24);
        Random random = new Random();

        Long randomNumber = -1L;

        // 生成随机数
        while (randomNumber < 0 || randomNumber > 4294967295L) {
            randomNumber  = Integer.toUnsignedLong(random.nextInt());
        }

        return buildUrl(serviceUrl, sdkAppId, identifier, userSig, randomNumber);
    }
}
